package com.snk.back.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.snk.back.dao.SysUserDao;
import com.snk.back.dao.SysUserRoleDao;
import com.snk.back.service.SysUserService;
import com.snk.common.annotation.RequiredLog;
import com.snk.common.exception.ServiceException;
import com.snk.common.pojo.PageObject;
import com.snk.common.utils.AssertUtils;
import com.snk.pojo.SysUser;
import com.snk.pojo.SysUserDept;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SysUserDao sysUserDao;
@Autowired
private SysUserRoleDao sysUserRoleDao;

    @RequiredLog
    @Override
    public PageObject<SysUserDept> findPageObjects(String username, Long pageCurrent) {

        AssertUtils.isValid(pageCurrent==null || pageCurrent<1,"当前页码值无效");

        int pageSize=3;
        //设置查询位置以及页面大小
        Page<SysUser> page= PageHelper.startPage(pageCurrent.intValue(),pageSize);
        //查询当前页数据
        List<SysUserDept> records=
                sysUserDao.findPageObjects(username);

        return new PageObject<>(page.getTotal(), records, pageSize, pageCurrent);
}

    @Override
    public int validById(Integer id, Integer valid) {
        AssertUtils.isValid(id==null||id<1, "参数值无效");
        AssertUtils.isValid(valid!=1&&valid!=0, "参数不合法。valid="+valid);
        //执行禁用或启用操作（admin为后续登陆用户
        int rows=sysUserDao.validById(id, valid, "admin");

        AssertUtils.isServiceValid(rows==0,"此记录可能已经不存在");
        return rows;
    }
    @RequiredLog
    @Override
    public int saveObject(SysUser sysUser, Integer[] roleIds) {
        long start=System.currentTimeMillis();
        log.info("start:"+start);
        AssertUtils.isValid(sysUser==null, "保存对象不能为空");
        AssertUtils.isValid(StringUtils.isEmpty(sysUser.getUsername()),"用户名不能为空");
        AssertUtils.isValid(StringUtils.isEmpty(sysUser.getPassword()),"密码不能为空");
        AssertUtils.isValid(roleIds==null || roleIds.length==0,"必须为用户分配角色");
        //保存用户自身信息
        //为密码加密
        String source=sysUser.getPassword();
        String salt= UUID.randomUUID().toString();
        //借组shiro框架中的API对密码进行加密
        SimpleHash sh=new SimpleHash(
                "MD5",//algorithmName 算法名称
                source,//原密码
                salt,//加密盐值
                1);//hashIterations表示加密次数
        String hashedPassword=sh.toHex();//将加密结果转换为16进行的字符串
        sysUser.setSalt(salt);//为什么颜值也要保存到数据库？一位登录时还要使用此salt对登录密码进行加密
        sysUser.setPassword(hashedPassword);
        int rows=sysUserDao.insertObject(sysUser);
        sysUserRoleDao.insertObjects(sysUser.getId(), roleIds);
        long end=System.currentTimeMillis();
        log.info("end:", end);
        log.info("total time", end-start);
        return rows;
    }
    @RequiredLog
    @Override
    public Map<String, Object> findObjectById(Integer userId) {
        //long t1=System.currentTimeMillis();//直接在雷芳芳中添加代码会违背开闭原则
        AssertUtils.isValid(userId==null || userId<=0,"参数数据不合法，userId="+userId);
        SysUserDept user=sysUserDao.findObjectById(userId);
        if(user==null)
            throw new ServiceException("此用户已经不存在");
 AssertUtils.isServiceValid(user==null, "此用户已经不存在");


        List<Integer> roleIds=
                sysUserRoleDao.findRoleIdsByUserId(userId);
        Map<String,Object> map=new HashMap<>();
        map.put("user", user);
        map.put("roleIds", roleIds);
        //long t2=System.currentTimeMillis();
        //log.info("time{}", t2-t1);
        return map;
    }
    @RequiredLog
    @Override
    public int updateObject(SysUser sysUser, Integer[] roleIds) {

        AssertUtils.isValid(sysUser==null, "保存对象不能为空");
        AssertUtils.isValid(StringUtils.isEmpty(sysUser.getUsername()),"用户名不能为空");
        AssertUtils.isValid(roleIds==null || roleIds.length==0,"必须为其指定角色");
        //更新用户自身信息
        int rows=sysUserDao.updateObject(sysUser);
        //保存用户与角色关系数据
        sysUserRoleDao.deleteObjectsByUserId(sysUser.getId());
        sysUserRoleDao.insertObjects(sysUser.getId(), roleIds);

        return rows;
    }
    @RequiredLog
    @Override
    public int updatePassword(String password, String newPassword, String cfgPassword) {

        AssertUtils.isValid(StringUtils.isEmpty(newPassword),"新密码不能为空");
        AssertUtils.isValid(StringUtils.isEmpty(cfgPassword),"确认密码不能为空");
        AssertUtils.isValid(StringUtils.isEmpty(cfgPassword),"两次输入的密码不相等");
        AssertUtils.isValid(StringUtils.isEmpty(password),"预案密码不能为空");
        SysUser user=
                (SysUser) SecurityUtils.getSubject().getPrincipal();
        SimpleHash sh=new SimpleHash("MD5",password,user.getSalt(),1);

        AssertUtils.isValid(!user.getPassword().equals(sh.toHex()),"原密码不正确");
        String salt=UUID.randomUUID().toString();
        sh=new SimpleHash("MD5",newPassword,salt,1);

        int rows=sysUserDao.updatePassword(sh.toHex(), salt, user.getId());

        AssertUtils.isServiceValid(rows==0,"修改失败");
        return rows;
    }


}
